<?php

namespace App\Request\auth\Service\Jwt;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Psr\Http\Message\ServerRequestInterface;
use function Hyperf\Config\config;

/**
 * JWT 服务类
 */
class JwtService
{
    protected string $guard;

    protected array $config;

    public function __construct(string $guard = '')
    {
        $this->guard = $guard ?: config('jwt.default', 'admin');
        $this->loadConfig();
    }

    protected function loadConfig(): void
    {
        $guards = config('jwt.guards', []);
        if (!isset($guards[$this->guard])) {
            throw new \InvalidArgumentException("JWT guard '{$this->guard}' not configured.");
        }
        $this->config = $guards[$this->guard];
    }

    /**
     * 生成 JWT Token
     * @param int $uid
     * @param array $data
     * @return string
     * @throws \Random\RandomException
     */
    public function getToken(int $uid, array $data = []): string
    {
        $time = time();

        $payload = array_merge([
            'iss' => $this->config['issuer'] ?? 'iot-control-system',
            'iat' => $time,
            'nbf' => $time,
            'exp' => $time + ($this->config['ttl'] ?? 3600),
            'jti' => bin2hex(random_bytes(16)),
            'sub' => $uid,
            "guard" =>$this->guard
        ], $data);

        return JWT::encode($payload, $this->config['secret'], $this->config['algo'] ?? 'HS256');
    }

    /**
     * 验证 Token 并返回解码后的 Payload 对象，失败返回 null
     */
    public function verifyToken(mixed $token = ""): bool|\stdClass
    {
        if (!$token) {
            return false;
        }
        try {
            return JWT::decode($token, new Key($this->config['secret'], $this->config['algo'] ?? 'HS256'));
        } catch (\Throwable $e) {
            // 这里可以记录日志
            return false;
        }
    }

    /**
     * 获取当前 guard 名称
     */
    public function getGuard(): string
    {
        return $this->guard;
    }

    /**
     * 切换 guard
     */
    public function setGuard(string $guard): self
    {
        $this->guard = $guard;
        $this->loadConfig();
        return $this;
    }

    /**
     * 从请求中获取 JWT Token
     * @param ServerRequestInterface $request
     * @return string|null
     */
    public function getTokenFromRequest(ServerRequestInterface $request): ?string
    {
        $authHeader = $request->getHeaderLine('Authorization');
        if ($authHeader && preg_match('/Bearer\s(\S+)/i', $authHeader, $matches)) {
            return $matches[1];
        }

        $params = $request->getQueryParams();
        if (!empty($params['token'])) {
            return $params['token'];
        }

        $parsedBody = $request->getParsedBody();
        if (is_array($parsedBody) && !empty($parsedBody['token'])) {
            return $parsedBody['token'];
        }

        return null;
    }
}
